package self.xine.basic.thread.communication;

import java.util.Random;

import self.xine.basic.thread.entity.MyQueue;

/**
 * 对多线程间的共享资源加锁，可以保证数据的正确性。
 * 	但若线程取得锁对象后，却发现需要满足某些条件才能继续执行，此时会在不断取得锁、释放锁，而没有做任务有意义的事。
 * 
 * 此时，便需要条件对象，当发现条件不满足时，调用其await方法，放弃持有锁，而进入该锁对象的对应条件的等待集中。
 *   直到其它线程操作后，使条件可能满足时，调用signall方法，使线程退出等待集，
 *    再重新取得锁后，执行await的下一条语句，因此有必要重新检测条件是否满足
 * 
 * @author xine
 * @date 2018年9月8日
 */
public class ConditionTest{
		
	public static void main(String[] args) {
		MyQueue<Object> myQueue = new MyQueue<Object>(5);
						
		Thread t1 = new Thread(new ConditionSubRunnable(myQueue),"取出线程");
		Thread t2 = new Thread(new ConditionAddRunnable(myQueue),"存放线程");
				
		t1.start();
		t2.start();		
		
		while(t1.isAlive() || t2.isAlive()) {
			System.out.println(t1.getName() + " " + t1.getState().name() + " " + t2.getName() + " " + t2.getState().name());
		}
		
	}

}



class ConditionSubRunnable implements Runnable {
	private MyQueue<Object> queueObject;
	
	public ConditionSubRunnable(MyQueue<Object> queueObject) {
		this.queueObject = queueObject;	
	}
	
	@Override
	public void run() {
		try {
			while(queueObject.length() < 10) {
				queueObject.remove();
			}
		}	
		catch (InterruptedException e) {
			e.printStackTrace();
		}	
	}
}

class ConditionAddRunnable implements Runnable {
	private MyQueue<Object> queueObject;
		
	public ConditionAddRunnable(MyQueue<Object> queueObject) {
		this.queueObject = queueObject;	
	}
	
	@Override
	public void run() {
		try {
			Random random = new Random();
			while(queueObject.length() < 10) {
				queueObject.add("test" + random.nextInt(10));
			}
		}	
		catch (InterruptedException e) {
			e.printStackTrace();
		}			
	}
}
